package org.hibiscus.jdp.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * 描述：IO 工具类
 *
 * @author rannuo
 * @date 2019/1/28
 */
public class IOUtils {

	private static final Logger log = LoggerFactory.getLogger(IOUtils.class);

	/**
	 * 输出二进制文件
	 *
	 * @param binaryData
	 * @param contentType
	 */
	public static void output(byte[] binaryData, String contentType) {
		HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();
		if (response == null) {
			return;
		}
		// 重置以便解决冲突
		response.reset();
		if (contentType != null && !"".equals(contentType)) {
			response.setContentType(contentType);
		}
		response.addHeader("Accept-Ranges", "bytes");
		response.setContentLength(binaryData.length);
		output(binaryData, response);
	}

	/**
	 * 下载
	 *
	 * @param binaryData
	 * @param filename
	 */
	public static void download(byte[] binaryData, String filename) {
		// 乱码处理
		try {
			filename = URLEncoder.encode(filename, "UTF-8");
			// URLEncoder编码，当中文文字超过17个时，IE6 无法下载文件
			if (filename.length() > 150) {
				// 根据request的locale 得出可能的编码，中文操作系统通常是gb2312
				String guessCharset = "gb2312";
				filename = new String(filename.getBytes(guessCharset), "ISO8859-1");
			}
		} catch (UnsupportedEncodingException e) {
			log.error("编码不支持！");
			return;
		}

		HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();
		if (response == null) {
			return;
		}
		// 重置以便解决冲突
		response.reset();
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/octet-stream");
		response.addHeader("Content-Disposition", "attachment; filename=" + filename);
		output(binaryData, response);
	}

	/**
	 * 输出
	 *
	 * @param binaryData
	 * @param response
	 */
	private static void output(byte[] binaryData, HttpServletResponse response) {
		if (binaryData == null) {
			return;
		}
		OutputStream stream = null;
		try {
			stream = response.getOutputStream();
			stream.write(binaryData);
			stream.flush();
		} catch (IOException ignored) {
			log.error("Failed to output data to client!");
		} finally {
			close(stream);
		}
	}

	/**
	 * 关闭流输出流
	 *
	 * @param stream
	 */
	private static void close(OutputStream stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				log.error("关闭OutputStream异常", e);
			}
		}
	}

	/**
	 * 获得指定文件的byte数组
	 *
	 * @param file
	 * @return
	 */
	public static byte[] getFileBytes(File file) throws IOException {
		FileInputStream fis = new FileInputStream(file);
		try (ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
			byte[] b = new byte[1024];
			int n;
			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}
			fis.close();
			return bos.toByteArray();
		}
	}

	/**
	 * inputStream转byte[]
	 *
	 * @param is
	 * @return
	 * @throws IOException
	 */
	public static byte[] inputStreamToBytes(InputStream is) throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		int len = 1024;
		byte[] tmp = new byte[len];
		int i;
		while ((i = is.read(tmp, 0, len)) > 0) {
			os.write(tmp, 0, i);
		}
		return os.toByteArray();
	}

	/**
	 * 获取文件后缀
	 *
	 * @param file
	 * @return
	 */
	public static String getFileSuffix(File file) {
		String suffix = null;
		if (file != null) {
			String originalFilename = file.getName();
			if (StringUtils.isNotBlank(originalFilename)) {
				String[] temp = originalFilename.split("\\.");
				if (temp.length > 1) {
					suffix = temp[temp.length - 1];
				}
			}
		}
		return suffix;
	}

}
